<template>
  <div class="layout">
    <header class="header">
      <div class="left">
        <div class="logo">
          <img src="../../assets/好大一只.png" alt="" />
        </div>
        <div class="collp" @click.stop="toggleClick">
          <tipsC :content="!isCollapse ? '折叠' : '展开'">
            <template #default>
              <el-icon v-if="isCollapse"><Menu /></el-icon>
              <el-icon v-else><Fold /></el-icon>
            </template>
          </tipsC>
        </div>
      </div>
      <div class="right">
        <div class="func">
          <div class="publish_notice" @click="newNotice">
            <tipsC :content="'发送通知'">
              <template #default>
                <el-icon>
                  <Plus />
                </el-icon>
              </template>
            </tipsC>
          </div>
          <div class="bell" ref="bellRef" v-click-outside="onClickOutside">
            <tipsC :content="'通知'">
              <template #default>
                <el-icon :class="isshowRedPoint ? '' : 'tips_red_point'"
                  ><Bell
                /></el-icon>
              </template>
            </tipsC>
          </div>
        </div>
        <div class="userinfo">
          <div class="info">
            <div class="name">{{ userInfo?.username }}</div>
            <div class="email">{{ userInfo?.email }}</div>
          </div>
          <div class="avatar" ref="buttonRef" v-click-outside="onClickOutside">
            <img src="../../assets/avatar.png" alt="" />
          </div>
          <PoppoverC ref="popoverref" :buttonRef="buttonRef"></PoppoverC>
        </div>
      </div>
    </header>
    <div class="content_box">
      <div class="sider">
        <div class="mmenu">
          <menuC :isCollapsed="isCollapse"></menuC>
        </div>
      </div>
      <div class="centent">
        <router-view></router-view>
      </div>
    </div>
    <footer class="footer">
      <a href="https://beian.miit.gov.cn/" target="_blank">
        备案号: 蜀ICP备2024086875号-1
      </a>
      <a
        href="https://www.douyin.com/user/MS4wLjABAAAAJxUIX2GMq0-rcucksrrllJj93HHnceibxk40_PWmeX0"
        target="_blank"
        >© 好大一只</a
      >
    </footer>
  </div>
  <el-popover
    ref="popoverRef"
    :virtual-ref="buttonRef"
    trigger="click"
    title=""
    virtual-triggering
  >
    <div class="little_menu">
      <div class="item">
        <router-link class="link" to="user/info">个人中心</router-link>
      </div>
      <div class="item">
        <router-link class="link" to="">修改资料</router-link>
      </div>
      <div class="item">
        <router-link class="link" to="">修改密码</router-link>
      </div>
      <div class="item">
        <router-link class="link" to="">退出登录</router-link>
      </div>
    </div>
  </el-popover>

  <el-popover
    width="400"
    height="100"
    class="bellpop"
    ref="bellpopRef"
    :virtual-ref="bellRef"
    trigger="click"
    title=""
    virtual-triggering
  >
    <div class="little_notice">
      <div
        v-if="notices.length > 0"
        class="item"
        v-for="notice in notices"
        :key="notice.id"
        @click="onClickNotice(notice.id)"
      >
        <div class="notice_type">
          {{ notice.noticeType === "important" ? "重要通知" : "一般通知" }} :
          <span>{{ notice.title }}</span>
        </div>
        <div class="content">{{ notice.content }}</div>
        <div class="time">
          <span class="isread">{{
            notice.status == "unread" ? "未读" : "已读"
          }}</span>
          <span>{{ notice.noticeTime }}</span>
        </div>
      </div>
    </div>
    <div v-if="notices.length <= 0" class="item">暂无通知</div>
  </el-popover>
</template>

<script setup lang="ts">
import { onMounted, ref, unref, h, onUnmounted } from "vue";
import {
  getNoticeInfo,
  getNoticeList,
  sendNotice,
  markNoticeRead,
} from "../../api/notice/index";
import { NewNoticeParams, Notice } from "../../types/common";
import { NoticeInfoParams, Notification } from "../../types/notice";
import { User } from "../../types/user";

import menuC from "./component/menuC.vue";
import noticeC from "./component/noticePopover.vue";
import tipsC from "./component/tips.vue";
import NewNotice from "./component/sendnotice.vue";
import { formatDate } from "../../utils";

import {
  ClickOutside as vClickOutside,
  ElMessageBox,
  ElMessage,
} from "element-plus";

import { useUserStore } from "../../store";
const buttonRef = ref();
const bellRef = ref();
const popoverRef = ref();
const store = useUserStore();
const bellpopRef = ref();

// 展示小红点
let isshowRedPoint = ref(false);
let isCollapse = ref(false);
let userInfo = ref<User>({
  id: 0, // JSON 中的 bigint 通常以 "" 格式表示
  username: "",
  password: "",
  age: 0,
  birth: "", // 可选的字段
  gender: 0,
  signature: "",
  email: "",
  cellphone: "",
  avatarUrl: "",
  createdAt: "", // 可选的字段
  updatedAt: "", // 可选的字段
  deletedAt: "", // 可选的字段
  isRemoved: 0,
  auth: {
    operate: [0],
    route: [0],
  },
});

/**
 * 获取用户数据
 */
getUserInfo();

async function getUserInfo() {
  const response = await store.fetchUserInfo(0);
  userInfo.value = response;
}

/**
 * 通知弹窗的数据
 */
const notices = ref<Notice[]>([]);
// 获取通知列表
async function getNoticeListApi() {
  // ts转化成Date类型
  const now = new Date();
  const oneWeekAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);

  const noticeListP = {
    start_time: formatDate(oneWeekAgo),
    end_time: formatDate(now),
    page: 1,
    limit: 5,
  };
  try {
    const response = await getNoticeList(noticeListP);
    if (response.code === 200) {
      notices.value = response.result.list ? response.result.list : [];
    }
    showRedPoint();
  } catch (error) {
    ElMessage({
      type: "error",
      message: "请求失败",
    });
  }
}
getNoticeListApi();
// 已读通知修改
const readNotice = async (id: string) => {
  const response = await markNoticeRead(Number(id));
  if (response.code === 200) {
    getNoticeListApi();
  }
};
// 获取通知列表
const onClickNotice = async (id: string) => {
  try {
    let noticeP: NoticeInfoParams = {
      n_id: id,
    };
    await readNotice(id);
    const response = await getNoticeInfo(noticeP);
    const result = response.result;
    if (response.code === 200) {
      ElMessageBox.confirm(h(noticeC, { result }), "通知详情", {
        cancelButtonText: "退出",
        draggable: true,
        showCancelButton: true,
        showConfirmButton: false,
        showClose: false,
        showInput: false,
      });
    }
  } catch (error) {
    ElMessage({
      type: "error",
      message: "请求失败",
    });
  }
};

/**
 *
 */

const onClickOutside = () => {
  unref(popoverRef).popperRef?.delayHide?.();
  unref(bellpopRef).bellpopRef?.delayHide?.();
};

// 在挂载的时候获取dom元素
onMounted(() => {
  // 监控屏幕滚动
  window.addEventListener(
    "resize",
    function (_: Event) {
      const widthC = window.innerWidth;
      const sider = document.querySelector(".sider") as HTMLElement;
      const contentBox = document.querySelector(".content_box") as HTMLElement;

      if (widthC <= 768) {
        sider.classList.add("hidden");
        if (sider.classList.contains("hidden")) {
          isCollapse.value = true;
        }
      } else {
        if (!isCollapse.value) {
          sider.classList.remove("hidden");
          contentBox.classList.remove("sider-hidden");
        } else {
          sider.classList.add("hidden");
          contentBox.classList.add("sider-hidden");
        }
      }
    },
    true
  );

  // 监控鼠标移动位置
  document.addEventListener("mousemove", function (event) {
    const footer = document.querySelector(".footer") as HTMLElement;
    const windowHeight = window.innerHeight;
    const mouseY = event.clientY;
    if (windowHeight - mouseY < 90) {
      footer.classList.add("hide_footer");
    } else {
      footer.classList.remove("hide_footer");
    }
  });
});
onUnmounted(() => {});

function toggleClick() {
  isCollapse.value = !isCollapse.value;
  toggleSider();
}

function toggleSider() {
  const contentBox = document.querySelector(".content_box") as HTMLElement;
  const sider = document.querySelector(".sider") as HTMLElement;

  if (sider.classList.contains("hidden")) {
    sider.classList.remove("hidden");
    contentBox.classList.remove("sider-hidden");
  } else {
    sider.classList.add("hidden");
    contentBox.classList.add("sider-hidden");
  }
}
// 新通知
function newNotice() {
  // 创建一个 ref 来保存组件实例
  const fromparam = ref<NewNoticeParams>({
    n_id: 0,
    sender_email: "",
    sender_username: "",
    sender_uid: 0,
    n_title: "",
    notice_type: "important",
    n_content: "",
    n_time: "",
    recipient: "all",
    recipientUIDs: [],
  });

  ElMessageBox.confirm(
    h(NewNotice, {
      modelValue: fromparam.value,
      "onUpdate:modelValue": (value: NewNoticeParams) =>
        (fromparam.value = value),
    }),
    "新通知",
    {
      cancelButtonText: "关闭",
      confirmButtonText: "发布",
      draggable: true,
      showCancelButton: true,
      showConfirmButton: true,
      showClose: false,
      showInput: false,
    }
  )
    .then(() => {
      if (fromparam.value) {
        let noticeParam: Notification = {
          id: "",
          senderEmail: "",
          senderUsername: "",
          senderUid: "", // JSON 中的 bigint 通常以 "" 格式表示
          title: "",
          noticeType: "important", // 枚举类型
          content: "",
          noticeTime: "", // ISO 8601 格式的日期时间字符串
          recipientType: "all", // 枚举类型
          recipientUIDs: [],
        };
        noticeParam.title = fromparam.value.n_title;
        noticeParam.content = fromparam.value.n_content;
        noticeParam.senderEmail = fromparam.value.sender_email;
        noticeParam.senderUsername = fromparam.value.sender_username;
        noticeParam.senderUid = fromparam.value.sender_uid.toString();
        noticeParam.noticeTime = formatDate(new Date());
        noticeParam.recipientType = fromparam.value.recipient;
        noticeParam.recipientUIDs = fromparam.value.recipientUIDs;
        noticeParam.noticeType = fromparam.value.notice_type;
        if (fromparam.value.recipientUIDs[0] == 0) {
          noticeParam.recipientType = "all";
        }
        if (
          fromparam.value.recipientUIDs.length >= 1 &&
          fromparam.value.recipientUIDs[0] != 0
        ) {
          noticeParam.recipientType = "specific";
        }
        sendNoticenew(noticeParam);
      }
    })
    .catch((_) => {
      ElMessage({
        message: "取消发布",
        type: "error",
      });
    });
}

// 发送新通知
async function sendNoticenew(params: Notification) {
  try {
    const response = await sendNotice(params);
    if (response.code === 200) {
      ElMessage({
        message: "发布成功",
        type: "success",
      });
      getNoticeListApi();
    } else {
      ElMessage({
        message: response.message,
        type: "error",
      });
    }
  } catch (error) {
    ElMessage({
      message: "发布失败",
      type: "error",
    });
  }
}

// 提示小红点是否显示
function showRedPoint() {
  let trueBox = [];
  for (let i = 0; i < notices.value.length; i++) {
    // 判断是否为已读
    if (notices.value[i].status === "unread") {
      isshowRedPoint.value = false; // 表示未读，红点显示
      return false;
    } else {
      trueBox.push(notices.value[i].status);
    }
  }
  if (trueBox.length === notices.value.length) {
    isshowRedPoint.value = true;
  }
}
</script>

<style lang="scss" scoped>
// 定义变量
$header-height: 60px;
$sider-width: 12.5rem;
$header-bg-color: #8cb0d8 !important;

.layout {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;

  .header {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    align-items: center;
    width: 100%;
    background-color: $header-bg-color;
    height: $header-height;
    z-index: 1;
    box-sizing: border-box;
    border-radius: 1.25rem;
    .left {
      height: $header-height;
      display: flex;
      flex-direction: row;
      border-radius: 1.25rem 0 0 1.25rem;
      .collp {
        display: flex;
        justify-content: center;
        align-items: center;
        color: #333;
      }
    }

    .right {
      height: $header-height;
      flex: 1;
      display: flex;
      justify-content: end;
      align-items: center;

      .func {
        display: flex;
        justify-content: space-between;
        width: max-content;
        align-items: center;
        margin-right: 2%;
        .bell {
          font-size: 20px;
          animation: swing 1s ease-in-out infinite;
          // 提示小红点
          .tips_red_point {
            &::after {
              content: "";
              position: absolute;
              top: 0rem;
              right: 0rem;
              width: 5px;
              height: 5px;
              border-radius: 50%;
              background-color: #ff4d4f;
            }
          }
        }
        .publish_notice {
          margin-right: 20px;
          &:hover {
            cursor: pointer;
          }
        }
      }

      .userinfo {
        width: max-content;
        display: flex;
        justify-content: end;
        align-items: center;
        margin-right: 30px;

        .info {
          margin-right: 20px;
          .name {
            font-weight: 700;
          }
          .email {
            font-size: 12px;
            color: #333;
          }
        }
        .avatar {
          width: 40px;
          height: 40px;
          border-radius: 50%;
          background-color: #007bff;
          display: flex;
          justify-content: center;
          align-items: center;
          &:hover {
            cursor: pointer;
          }
          img {
            border-radius: 50%;
          }
        }
      }
    }
  }

  .logo {
    display: flex;
    align-items: center;
    justify-content: center;
    width: $sider-width;
    height: $header-height;
    border-radius: 1.25rem 0 0 1.25rem;
    background-color: $header-bg-color;
    img {
      height: 60px;
      transform: scale(2.5);
    }
  }

  .content_box {
    display: grid;
    grid-template-columns: $sider-width 1fr; // 初始状态：侧边栏和内容区域
    grid-auto-rows: minmax(min-content, max-content);
    width: 100%;
    overflow-y: auto;

    &.sider-hidden {
      // grid-template-columns: 1fr; // 侧边栏隐藏时，内容区域占满整个宽度
      grid-template-columns: 0; // 侧边栏隐藏时，内容区域占满整个宽度
    }

    .sider {
      grid-column: 1 / 2;
      background-color: $header-bg-color;
      box-sizing: border-box;
      z-index: 1;
      border-radius: 10px;
      margin-top: 5%;
      position: relative;
      height: 99.5%;
      .mmenu {
        padding-top: 10px;
      }
      &.hidden {
        display: none; // 隐藏侧边栏
      }
    }

    .centent {
      grid-column: 2 / 3;
      box-sizing: border-box;
      background-color: #f5f5f5;
      position: relative;
      // 默认情况下,内容区域占满剩余的宽度
    }
  }
}

.footer {
  position: fixed;
  width: 100%;
  height: 40px;
  left: 0;
  bottom: 0;
  font-size: 14px;
  color: #555;
  background-color: #f9f9f9;
  padding: 15px;
  border-top: 1px solid #ddd;
  text-align: center;
  visibility: hidden;

  a {
    color: #007bff;
    text-decoration: none;
  }

  a:hover {
    text-decoration: underline;
  }
}
// 隐藏footer
.hide_footer {
  visibility: visible;
}

.footer span {
  display: block;
  margin-bottom: 5px;
}

.footer.copyright {
  font-style: italic;
}

.footer.icp {
  font-weight: bold;
}
// 铃铛的 晃动效果
// 铃铛摆动动画
@keyframes swing {
  0% {
    transform-origin: 50% 50%;
    transform: rotate(0deg);
  }

  25% {
    transform-origin: 50% 50%;
    transform: rotate(10deg);
  }

  50% {
    transform-origin: 50% 50%;
    transform: rotate(-10deg);
  }

  75% {
    transform-origin: 50% 50%;
    transform: rotate(5deg);
  }

  100% {
    transform-origin: 50% 50%;
    transform: rotate(0deg);
  }
}

// 弹出框
.little_menu {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  .item {
    width: 100%;
    padding: 5px;
    text-align: center;
    .link {
      color: #333;
      font-family: "fangsong";
    }
    &:hover {
      cursor: pointer;
      background-color: #8cb0d8;
      .link {
        color: #fff;
      }
    }
  }
}

// 通知弹出框
.little_notice {
  height: 100%;
  width: 100%;
  overflow-x: scroll;
  .item {
    position: relative;
    width: 100%;
    height: 70px;
    margin: 5px;
    border-bottom: 1px solid #ccc;
    &:hover {
      cursor: pointer;
      .content {
        background-color: #acd1f0;
        color: #333;
      }
    }
    .notice_type {
      font-weight: 600;
      span {
        color: #797777;
      }
    }
    .content {
      // 文本超出部分显示省略号
      overflow: hidden;
      text-overflow: ellipsis;
      display: -webkit-box;
      -webkit-line-clamp: 2;
      -webkit-box-orient: vertical;
      font-size: 12px;
      color: #666;
    }
    .time {
      position: absolute;
      right: 5px;
      bottom: 0;
      font-weight: 300;
      font-size: 12px;
      .isread {
        margin-right: 10px;
      }
    }
  }
}

// 媒体查询控制显示隐藏 ，当屏幕小于 768px 时，隐藏，当屏幕大于 768px 时，显示
// @media (min-width: 1540px) {
//   .layout {
//     .content_box {
//       .sider,
//       .centent {
//         // height: calc(100vh - $header-height - 10px); // 高度占满屏幕
//       }
//     }
//   }
// }

@media (max-width: 770px) {
  .layout {
    .content_box {
      // grid-template-columns: 1fr !important; // 侧边栏隐藏时，内容区域占满整个宽度
      grid-template-columns: 0 !important; // 侧边栏隐藏时，内容区域占满整个宽度
      .sider .hidden {
        display: none; // 隐藏侧边栏
      }
    }
  }
}

@media (max-width: 480px) {
  .layout {
    .header {
      .logo {
        display: none; // 隐藏 logo
      }
    }
  }
}
</style>
